package com.sam.admin.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class HttpClientUtil {

    private CloseableHttpClient httpClient;

    public HttpClientUtil(CloseableHttpClient httpClient){
        this.httpClient = httpClient;
    }

    /**
     * get请求
     * @param url
     * @param param
     * @param head
     * @return
     * @throws URISyntaxException
     */
    public HttpResponse doGet(String url, Map<String,Object> param, Map<String,String> head) throws Exception {
        // 声明URIBuilder
        URIBuilder uriBuilder = new URIBuilder(url);
        // 判断参数map是否为非空
        if (param != null) {
            // 遍历参数
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                if(entry.getValue()!=null) {
                    // 设置参数
                    uriBuilder.setParameter(entry.getKey(), String.valueOf(entry.getValue()));
                }
            }
        }
        // 2 创建httpGet对象，相当于设置url请求地址
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        HttpResponse httpResponse = doSend(httpGet,head);
//        httpGet.abort();
        return httpResponse;
    }

    /**
     * post请求 支持content-type:application/x-www-form-urlencoded
     * @param url
     * @param param
     * @param head
     * @return
     */
    public HttpResponse doPost(String url,Map<String,Object> param,Map<String,String> head){
        HttpPost httpPost = new HttpPost(url);
        if(param != null){
            // 声明存放参数的List集合
            val params = new ArrayList<NameValuePair>();
            // 遍历map，设置参数到list中
            for (Map.Entry<String, Object> entry : param.entrySet()) {
                if(entry.getValue()!=null) {
                    params.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
                }
            }
            // 创建form表单对象
            val formEntity = new UrlEncodedFormEntity(params, Consts.UTF_8);
            // 把表单对象设置到httpPost中
            httpPost.setEntity(formEntity);
        }
        HttpResponse httpResponse = doSend(httpPost,head);
        return httpResponse;
    }

    /**
     * post请求 支持content-type:application/json
     * @param url
     * @param jsonStr
     * @param head
     * @return
     */
    public HttpResponse doPost(String url, String jsonStr,Map<String,String> head){
        HttpPost httpPost = new HttpPost(url);
        if(head ==null){
            head = new HashMap<String,String>();
        }
        head.put("Content-type","application/json");
        StringEntity stringEntity = new StringEntity(jsonStr,Consts.UTF_8);
        httpPost.setEntity(stringEntity);
        HttpResponse httpResponse = doSend(httpPost, head);
        return httpResponse;
    }

    /**
     * put请求 支持content-type:application/x-www-form-urlencoded
     * @param url
     * @param map
     * @param headers
     * @return
     * @throws Exception
     */
    public HttpResponse doPut(String url, Map<String, Object> map, Map<String, String> headers){
        // 声明httpPost请求
        HttpPut httpPut = new HttpPut(url);
        // 判断map不为空
        if (map != null) {
            // 声明存放参数的List集合
            val params = new ArrayList<NameValuePair>();
            // 遍历map，设置参数到list中
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if(entry.getValue()!=null) {
                    params.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
                }
            }
            // 创建form表单对象
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, Consts.UTF_8);
            // 把表单对象设置到httpPost中
            httpPut.setEntity(formEntity);
        }
        // 使用HttpClient发起请求，返回response
        HttpResponse httpResponse = doSend(httpPut, headers);
        // 返回结果
        return httpResponse;
    }

    /**
     * put请求 支持content-type:application/json
     * @param url
     * @param headers
     * @return
     * @throws Exception
     */
    public HttpResponse doPut(String url, String jsonStr, Map<String, String> headers){
        // 声明httpPost请求
        HttpPut httpPut = new HttpPut(url);
        if(headers == null){
            headers = new HashMap<String,String>();
        }
        headers.put("Content-type","application/json");
        StringEntity stringEntity = new StringEntity(jsonStr,Consts.UTF_8);
        httpPut.setEntity(stringEntity);
        HttpResponse httpResponse = doSend(httpPut, headers);
        return httpResponse;
    }

    /**
     * delete请求：支持content-type:application/x-www-form-urlencoded
     * @param url
     * @param map
     * @param headers
     * @return
     * @throws Exception
     */
    public HttpResponse doDelete(String url, Map<String, Object> map, Map<String, String> headers) throws Exception{

        // 声明URIBuilder
        URIBuilder uriBuilder = new URIBuilder(url);
        // 判断参数map是否为非空
        if (map != null) {
            // 遍历参数
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if(entry.getValue()!=null) {
                    // 设置参数
                    uriBuilder.setParameter(entry.getKey(), String.valueOf(entry.getValue()));
                }
            }
        }
        // 2 创建httpGet对象，相当于设置url请求地址
        HttpDelete httpDelete = new HttpDelete(uriBuilder.build());
        // 3 使用HttpClient执行httpGet，相当于按回车，发起请求
        HttpResponse httpResponse = doSend(httpDelete, headers);
        // 返回
        return httpResponse;
    }

    private HttpResponse doSend(HttpUriRequest httpUriRequest,Map<String,String> headers){
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpUriRequest.addHeader(entry.getKey(), entry.getValue());
            }
        }
        log.info("httpUriRequest:{}", JSON.toJSONString(httpUriRequest.getURI()));
        HttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpUriRequest);
        } catch (IOException e) {
            httpUriRequest.abort();
            e.printStackTrace();
        }
        return httpResponse;
    }

}
